package com.igoal.web;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.igoal.dto.UserDTO;
import com.igoal.entity.HobbyCategory;
import com.igoal.service.MessageManager;
import com.igoal.service.SaveResult;
import com.igoal.service.UserAccountService;
import com.igoal.service.UserManagerExt;
import com.igoal.utils.StringUtils;
import com.igoal.web.model.AccountSettingModel;
import com.igoal.web.model.BaseModel;
import com.igoal.web.model.UserBasicInfoModel;
import com.igoal.web.model.UserContactInfoModel;
import com.igoal.web.model.UserHobbyInfoModel;
import com.igoal.web.model.UserPasswordInfoModel;

@Controller
public class AccountSettingController extends BaseController {

	private static Log logger = LogFactory
			.getLog(AccountSettingController.class);

	@Autowired
	public void setUserManagerExt(UserManagerExt userManagerExt) {
		this.userManagerExt = userManagerExt;
	}

	@Autowired
	public void setMessageManager(MessageManager messageManager) {
		this.messageManager = messageManager;
	}
	
	public String getViewPrefix() {
		return BaseControllerDelegate.DEFAULT_VIEW_PREFIX;
	}

	@RequestMapping(value = "/accountSetting.html", method = RequestMethod.GET)
	public String showAccountSetting(ModelMap model, HttpServletRequest request) {
		UserDTO user = getUserSession();
		initModel(model, user);
		return getViewPrefix() + "accountSetting";
	}

	@RequestMapping(value = "/setting/updateBasicInfo*", method = RequestMethod.POST)
	public ModelAndView updateBasicInfo(
			@ModelAttribute("userBasicInfo") UserBasicInfoModel userBasicInfo) {
		logger.info("Account setting - Save user's basic information");
		UserDTO user = userManagerExt.getUserByUsername(getUserInSession());
		user.setFirstName(userBasicInfo.getFirstName());
		user.setMiddleName(userBasicInfo.getMidleName());
		user.setLastName(userBasicInfo.getLastName());
		user.setPhone(userBasicInfo.getPhone());
		user.setMobilePhone(userBasicInfo.getMobilePhone());
		user.setCity(userBasicInfo.getCity());
		user.setAddress(userBasicInfo.getAddress());
		user.setMale(userBasicInfo.getGender() == 0);

		int bdDate = userBasicInfo.getBirthdayDate();
		int bdMonth = userBasicInfo.getBirthdayMonth();
		int bdYear = userBasicInfo.getBirthdayYear();
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DATE, bdDate);
		cal.set(Calendar.MONTH, bdMonth - 1);
		cal.set(Calendar.YEAR, bdYear);
		Date bd = cal.getTime();
		user.setBirthday(bd);

		userManagerExt.saveUserBasicInfo(user);
		return new ModelAndView(new SubmitSuccessView());
	}

	@RequestMapping(value = "/setting/updateContactInfo*", method = RequestMethod.POST)
	public ModelAndView updateContactInfo(
			@ModelAttribute("userConSaveResult.SUCCESStactInfo") UserContactInfoModel userContactInfo) {
		logger.info("Account setting - Save user's contact information");
		UserDTO user = userManagerExt.getUserByUsername(getUserInSession());
		
		user.setYahoo(userContactInfo.getYahooId());
		user.setGoogle(userContactInfo.getGoogleId());
		user.setSkype(userContactInfo.getSkypeId());
		
		int result = userManagerExt.saveUserContactInfo(user);
		if (result == SaveResult.SUCCESS) {
			return new ModelAndView(new SubmitSuccessView());
		} else {
			return new ModelAndView(new SubmitFailView());
		}
	}

	@RequestMapping(value = "/setting/updateHobbyInfo*", method = RequestMethod.POST)
	public ModelAndView updateHobbyInfo(
			@ModelAttribute("userHobbyInfo") UserHobbyInfoModel userHobbyInfo) {
		logger.info("Account setting - Save user's hobby information");
		UserDTO user = userManagerExt.getUserByUsername(getUserInSession());
		Map<String, Set<String>> userHobbies = new HashMap<String, Set<String>>();
		user.setHobbies(userHobbies);
		
		String music = userHobbyInfo.getMusicHobby();
		if (StringUtils.isNotBlank(music)) {
			String[] musicHobbies = music.split(",");
			String category = HobbyCategory.MUSIC;
			Set<String> hs = new HashSet<String>();
			for (String name : musicHobbies) {
				name = name.trim();
				hs.add(name);
			}
			userHobbies.put(category, hs);
		}

		String movie = userHobbyInfo.getMovieHobby();
		if (StringUtils.isNotBlank(movie)) {
			String[] movieHobbies = movie.split(",");
			String category = HobbyCategory.MOVIE;
			Set<String> hs = new HashSet<String>();
			for (String name : movieHobbies) {
				name = name.trim();
				hs.add(name);
			}
			userHobbies.put(category, hs);
		}

		String food = userHobbyInfo.getFoodHobby();
		if (StringUtils.isNotBlank(food)) {
			String[] foodHobbies = food.split(",");
			String category = HobbyCategory.FOOD;
			Set<String> hs = new HashSet<String>();
			for (String name : foodHobbies) {
				name = name.trim();
				hs.add(name);
			}
			userHobbies.put(category, hs);
		}

		int result = userManagerExt.saveUserHobbyInfo(user);
		if (result == SaveResult.SUCCESS) {
			return new ModelAndView(new SubmitSuccessView());
		} else {
			return new ModelAndView(new SubmitFailView());
		}
	}

	@RequestMapping(value = "/setting/updatePassInfo*", method = RequestMethod.POST)
	public ModelAndView updatePasswordInfo(
			@RequestParam("oldPass") String oldPass,
			@RequestParam("newPass") String newPass) {
		logger.info("Account setting - Save user's password information");
		int result = userManagerExt.saveUserPasswordInfo(getUserSession(),
				oldPass, newPass);

		if (result == SaveResult.SUCCESS) {
			return new ModelAndView(new SubmitSuccessView());
		} else {
			return new ModelAndView(new SubmitFailView());
		}
	}

	private void initModel(ModelMap modelMap, UserDTO user) {
		if (modelMap == null || user == null) {
			return;
		}

		AccountSettingModel model = new AccountSettingModel();
		simpleModelInitialize(user, model);
		initSessionInformation(model);

		// basic info
		UserBasicInfoModel userBasicInfo = new UserBasicInfoModel();
		userBasicInfo.setFirstName(user.getFirstName());
		userBasicInfo.setMidleName(user.getMiddleName());
		userBasicInfo.setLastName(user.getLastName());
		userBasicInfo.setPhone(user.getPhone());
		userBasicInfo.setMobilePhone(user.getMobilePhone());
		userBasicInfo.setAddress(user.getAddress());
		Calendar bd = Calendar.getInstance();
		bd.setTime(user.getBirthday());
		userBasicInfo.setBirthdayDate(bd.get(Calendar.DATE));
		userBasicInfo.setBirthdayMonth(bd.get(Calendar.MONTH) + 1);
		userBasicInfo.setBirthdayYear(bd.get(Calendar.YEAR));
		userBasicInfo.setEmail(user.getEmail());
		if (user.isMale()) {
			userBasicInfo.setGender(0);
		} else {
			userBasicInfo.setGender(1);
		}

		// contact info
		UserContactInfoModel userContactInfo = new UserContactInfoModel();
		userContactInfo.setGoogleId(user.getGoogle());
		userContactInfo.setYahooId(user.getYahoo());
		userContactInfo.setSkypeId(user.getSkype());

		// job/school info

		// hobby info
		UserHobbyInfoModel userHobbyInfo = new UserHobbyInfoModel();
		Map<String, Set<String>> hobbies = user.getHobbies();
		for (Entry<String, Set<String>> entry : hobbies.entrySet()) {
			String category = entry.getKey();
			Set<String> hList = entry.getValue();
			if (HobbyCategory.MUSIC.equals(category)) {
				String music = buildHobbyString(hList);
				userHobbyInfo.setMusicHobby(music);
			} else if (HobbyCategory.MOVIE.equals(category)) {
				String movie = buildHobbyString(hList);
				userHobbyInfo.setMovieHobby(movie);
			} else if (HobbyCategory.FOOD.equals(category)) {
				String food = buildHobbyString(hList);
				userHobbyInfo.setFoodHobby(food);
			}
		}

		// password info
		UserPasswordInfoModel userPassInfo = new UserPasswordInfoModel();

		modelMap.addAttribute("data", model);
		modelMap.addAttribute("userBasicInfo", userBasicInfo);
		modelMap.addAttribute("userContactInfo", userContactInfo);
		modelMap.addAttribute("userHobbyInfo", userHobbyInfo);
		modelMap.addAttribute("userPassInfo", userPassInfo);

		createReferenceData(modelMap);
	}

	private void createReferenceData(ModelMap modelMap) {
		Map<String, String> birthdayDate = new LinkedHashMap<String, String>();
		birthdayDate.put("-1", "Date:");
		for (int i = 1; i <= 31; i++) {
			birthdayDate.put("" + i, "" + i);
		}

		// TODO: get text from message.properties
		Map<String, String> birthdayMonth = new LinkedHashMap<String, String>();
		birthdayMonth.put("-1", "Month:");
		birthdayMonth.put("1", "Jan");
		birthdayMonth.put("2", "Feb");
		birthdayMonth.put("3", "Mar");
		birthdayMonth.put("4", "Apr");
		birthdayMonth.put("5", "May");
		birthdayMonth.put("6", "Jun");
		birthdayMonth.put("7", "Jul");
		birthdayMonth.put("8", "Aug");
		birthdayMonth.put("9", "Sep");
		birthdayMonth.put("10", "Oct");
		birthdayMonth.put("11", "Nov");
		birthdayMonth.put("12", "Dec");

		Map<String, String> birthdayYear = new LinkedHashMap<String, String>();
		birthdayYear.put("-1", "Year:");
		for (int i = 2010; i > 1900; i--) {
			birthdayYear.put("" + i, "" + i);
		}

		Map<String, String> gender = new LinkedHashMap<String, String>();
		gender.put("-1", "Gender:");
		gender.put("0", "Male");
		gender.put("1", "Female");

		modelMap.addAttribute("birthdayDateList", birthdayDate);
		modelMap.addAttribute("birthdayMonthList", birthdayMonth);
		modelMap.addAttribute("birthdayYearList", birthdayYear);
		modelMap.addAttribute("genderList", gender);
	}
	
	private String buildHobbyString(Set<String> hList) {
		String s = "";
		for (String h : hList) {
			s += ", " + h;
		}
		if (s.startsWith(",")) {
			s = s.substring(1).trim();
		}
		return s;
	}

	public void initTopPage(BaseModel model, HttpServletRequest request) {
		// TODO Auto-generated method stub
		
	}

	public void initRightPage(BaseModel model, HttpServletRequest request) {
		// TODO Auto-generated method stub
		
	}

	public void initLeftPage(BaseModel model, HttpServletRequest request) {
		// TODO Auto-generated method stub
		
	}
}
